use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;

#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub username: String,
    #[serde(skip_serializing)]
    pub password: String,
    pub max_bandwidth_up: i64,
    pub max_bandwidth_down: i64,
    pub traffic_limit: Option<i64>,
    pub traffic_used: i64,
    pub expire_at: Option<DateTime<Utc>>,
    pub enabled: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Deserialize)]
pub struct CreateUserRequest {
    pub username: String,
    pub password: String,
    #[serde(default)]
    pub max_bandwidth_up: i64,
    #[serde(default)]
    pub max_bandwidth_down: i64,
    pub traffic_limit: Option<i64>,
    pub expire_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Deserialize)]
pub struct UpdateUserRequest {
    pub password: Option<String>,
    pub max_bandwidth_up: Option<i64>,
    pub max_bandwidth_down: Option<i64>,
    pub traffic_limit: Option<i64>,
    pub expire_at: Option<DateTime<Utc>>,
    pub enabled: Option<bool>,
}

impl User {
    pub fn is_expired(&self) -> bool {
        if let Some(expire_at) = self.expire_at {
            expire_at < Utc::now()
        } else {
            false
        }
    }

    pub fn is_traffic_exceeded(&self) -> bool {
        if let Some(limit) = self.traffic_limit {
            self.traffic_used >= limit
        } else {
            false
        }
    }

    pub fn can_connect(&self) -> bool {
        self.enabled && !self.is_expired() && !self.is_traffic_exceeded()
    }
}
